Frontend.ctrl.profile = function() {
	var store = {

	// filter default option
	}, _filter = function(self) {
		var i = self,
			s = i.parent().find('span'),
			v = i.val();

		if(v.length > 0) s.hide();
		else s.fadeIn('fast');

	// bind for filter
	}, fields = function() {
		$('input[type="password"]', '#profile').each(function() {
			var self = $(this);

			_filter(self);
			self.on('input', function(){ _filter(self); });
		});

	// decode
	}, decode = function() {
		var x = $('span.matrix'),
			y = $('a#auth', 'div.metro').data('token');

		if(!$('span.matrix').length > 0)
			return;

		if(!y)
			return x.html('Hidden');

		var a = x.data('key'),
			b = a.split("").sort().join(""),
			c = x.data('code'),
			d = "", e;

		for(e = 0; e < c.length; e++)
			d += b.charAt(a.indexOf(c.charAt(e)));

		x.html('<a href="mailto:' + d + '">' + d + '</a>');

	// intercept
	}, intercept = function() {
		// change password form
		$('form#form_password', '#profile').on('submit', function(e){
			e.preventDefault();
			var post = $(this).serialize(),
				b = $('button', '#form_password');

			// check old password with ajax
			checkOld($('input[name="old"]', '#form_password'), function() {
				// for every form field
				$('input[type="password"]', '#form_password').each(function() {
					var o = $(this);
						n = o.attr('name').replace('_', ' '),
						N = n.replace(/^([a-z])|\s+([a-z])/g, function ($1) {
							return $1.toUpperCase();
						});

					// check if blank
					if(!$.trim(o.val()).length > 0) {
						Frontend.noty({type: 'error', text: N +' is blank'});
						o.addClass('error');
						o.val('');
						_filter(o);
					}
				});

				// check for password confirm
				var c = $('input[name="confirm"]', '#form_password');
				if($.trim(c.val()).length > 0 && $('input[name="password"]', '#form_password').val() != c.val()) {
					Frontend.noty({type: 'error', text: 'Passwords don\'t match'});
					c.addClass('error');
				}

				// check for errors
				var error = false;
				$('input[type="password"]', '#form_password').each(function() {
					if($(this).hasClass('error'))
						error = true;
				});

				// stop if errors found
				if(error)
					return false;

				// do signup procedure
				b.attr('disabled', 'disabled');
				Frontend.ajax({type: 'post', data: post, url: 'profile/change', success: function(data){
					b.removeAttr('disabled');

					// send message & refresh token
					Frontend.noty({type: 'information', text: 'Password changed!'});
					Frontend.go(window.location.href);
				}});
			});
		});

	// check name with ajax
	}, checkOld = function(self, f) {
		var o = self;

		// no value ? callback
		if(!$.trim(o.val()).length > 0)
			return f();

		// do ajax
		Frontend.ajax({type: 'post', data: {old: o.val()}, url: 'profile/check',
			success: function(data) {
				o.addClass('valid');
				f();
			}, error: function() {
				Frontend.noty({type: 'error', text: 'Wrong password'});
				o.removeClass().addClass('error');
				f();
			}
		});

	// bind events
	}, bind = function() {
		// on button click
		$('button', 'form.profile_handlers').on('click', function(e) {
			e.preventDefault();
			var b = $(this);

			// change password
			if(b.data('handle') == 'password')
				Frontend.go('profile/password');

			// logout
			else Frontend.logout('profile/view/' + b.data('link'));
		});

		// on any input change, loose the error
		$('input[type="password"]', '#profile').on('input', function() {
			$(this).removeClass();
		});

	// offline updater
	}, offline = function() {
		// update to offline in 1 second
		window.setTimeout(function() {
			// already updated from socket io? abort
			if($("#profile #location > a").length != 0)
				return;

			// set as offline
			$("#profile #location").html('Offline');
		}, 1000);

	// constructor
	}, __construct = function() {
		fields();
		decode();
		bind();
		intercept();
		offline();

		// select first element (not a button, not hidden) from the first form
		$('form:first *:input[type!=hidden]:not(button):first').focus();
	};

	// public, yay
	return {
		init: __construct
	};
}();